home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / setup / vbnet / 11 object serialization / serializationdemo / classes.vb < prev    next >
Encoding:
Text File  |  2002-03-16  |  8.9 KB  |  267 lines

  1. Imports System.Runtime.Serialization
  2.  
  3. ' a serializable Person class
  4.  
  5. <Serializable()> _
  6. Class Person
  7.     Public FirstName As String
  8.     Public LastName As String
  9.     Private BirthDate As Date
  10.  
  11.     ' don't serialize this field, which can be easily recalculated
  12.     <NonSerialized()> Private m_Age As Integer
  13.  
  14.     ' this field might cause circular references.
  15.     Public Spouse As Person
  16.  
  17.     ' Note that BirthDate can be set only through the constructor method.
  18.     Sub New(ByVal FirstName As String, ByVal LastName As String, _
  19.         ByVal BirthDate As Date)
  20.         Me.FirstName = FirstName
  21.         Me.LastName = LastName
  22.         Me.BirthDate = BirthDate
  23.     End Sub
  24.  
  25.     ' The Age property caches its value in the m_Age private variable.
  26.  
  27.     ReadOnly Property Age() As Integer
  28.         Get
  29.             ' Evaluate the Age if not cached already.
  30.             If m_Age = 0 Then m_Age = Year(Now) - Year(BirthDate)
  31.             Return m_Age
  32.         End Get
  33.     End Property
  34. End Class
  35.  
  36. ' a class that supports custom serialization
  37.  
  38. <Serializable()> _
  39. Class CompactDoubleArray
  40.     Inherits ArrayList
  41.     Implements ISerializable
  42.  
  43.     ' Elements that have this value aren't persisted.
  44.     Public DefaultValue As Double
  45.  
  46.     ' We need this default constructor, otherwise the class
  47.     ' couldn't be instantiated from regular clients. 
  48.     Sub New()
  49.         MyBase.New()
  50.     End Sub
  51.  
  52.     ' The special constructor implied by ISerializable.
  53.     Private Sub New(ByVal info As SerializationInfo, _
  54.         ByVal context As StreamingContext)
  55.  
  56.         ' Create the base ArrayList object.
  57.         MyBase.New()
  58.         ' Retrieve DefaultValue.
  59.         DefaultValue = info.GetDouble("DefaultValue")
  60.         ' Retrieve number of elements.
  61.         Dim elCount As Integer = info.GetInt32("Count")
  62.  
  63.         Dim index As Integer, Value As Double
  64.         For index = 0 To elCount - 1
  65.             Try
  66.                 ' Try to assign the value in the SerializationInfo.
  67.                 Value = info.GetDouble(index.ToString)
  68.             Catch
  69.                 ' If SerializeInfo doesn't contain that value, 
  70.                 ' use the default value.
  71.                 Value = DefaultValue
  72.             End Try
  73.             ' Add the value to the inner ArrayList.
  74.             MyBase.Add(Value)
  75.         Next
  76.     End Sub
  77.  
  78.     ' Serialize this object.
  79.     Sub GetObjectData(ByVal info As SerializationInfo, _
  80.         ByVal context As StreamingContext) _
  81.         Implements ISerializable.GetObjectData
  82.  
  83.         ' Remember DefaultValue.
  84.         info.AddValue("DefaultValue", DefaultValue)
  85.         ' Remember the total number of elements.
  86.         info.AddValue("Count", MyBase.Count)
  87.  
  88.         ' Serialize only elements whose value is different from DefaultValue.
  89.         Dim index As Integer, Value As Double
  90.         For index = 0 To MyBase.Count - 1
  91.             ' The AddValue method requires a specific type.
  92.             Value = CType(MyBase.Item(index), Double)
  93.             If Value <> DefaultValue Then
  94.                 ' Store only if different from default value.
  95.                 info.AddValue(index.ToString, Value)
  96.             End If
  97.         Next
  98.     End Sub
  99. End Class
  100.  
  101. ' a modified version of the class, that compacts data only when saving 
  102. ' to a file or a remote machine
  103.  
  104. <Serializable()> _
  105. Class CompactDoubleArray2
  106.     Inherits ArrayList
  107.     Implements ISerializable
  108.  
  109.     ' Elements that have this value aren't persisted.
  110.     Public DefaultValue As Double
  111.  
  112.     ' We need this default constructor, otherwise the class
  113.     ' couldn't be instantiated from regular clients. 
  114.     Sub New()
  115.         MyBase.New()
  116.     End Sub
  117.  
  118.     ' The special constructor implied by ISerializable.
  119.     Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
  120.         ' Create the base ArrayList object.
  121.         MyBase.New()
  122.  
  123.         ' Attempt to get the serialized ArrayList.
  124.         Try
  125.             ' Try to read an element named ArrayList.
  126.             Dim al As ArrayList
  127.             al = DirectCast(info.GetValue("ArrayList", GetType(ArrayList)), ArrayList)
  128.             ' If all went well, add to inner ArrayList and exit.
  129.             MyBase.AddRange(al)
  130.             Exit Sub
  131.         Catch
  132.             ' if failed, continue to extract elements.
  133.         End Try
  134.  
  135.         ' Retrieve DefaultValue.
  136.         DefaultValue = info.GetDouble("DefaultValue")
  137.         ' Retrieve number of elements.
  138.         Dim elCount As Integer = info.GetInt32("Count")
  139.  
  140.         Dim index As Integer, Value As Double
  141.         For index = 0 To elCount - 1
  142.             Try
  143.                 ' Try to assign the value in the SerializationInfo.
  144.                 Value = info.GetDouble(index.ToString)
  145.             Catch
  146.                 ' If SerializeInfo doesn't contain that value, 
  147.                 ' use the default value.
  148.                 Value = DefaultValue
  149.             End Try
  150.             ' Add the value to the inner ArrayList.
  151.             MyBase.Add(Value)
  152.         Next
  153.     End Sub
  154.  
  155.     ' Serialize this object.
  156.     Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) _
  157.         Implements ISerializable.GetObjectData
  158.  
  159.         ' If not serializing to a file or a remote machine, 
  160.         ' then use non non-compact format.
  161.         If context.State <> StreamingContextStates.File And context.State <> StreamingContextStates.CrossMachine Then
  162.             ' Serialize the inner ArrayList and exit.            
  163.             info.AddValue("ArrayList", MyBase.Clone)
  164.             Exit Sub
  165.         End If
  166.  
  167.         ' Remember DefaultValue.
  168.         info.AddValue("DefaultValue", DefaultValue)
  169.         ' Remember the total number of elements.
  170.         info.AddValue("Count", MyBase.Count)
  171.  
  172.         ' Serialize only elements whose value is different from DefaultValue.
  173.         Dim index As Integer, Value As Double
  174.         For index = 0 To MyBase.Count - 1
  175.             ' The AddValue method requires a specific type.
  176.             Value = CType(MyBase.Item(index), Double)
  177.             If Value <> DefaultValue Then
  178.                 ' Store only if different from default value.
  179.                 info.AddValue(index.ToString, Value)
  180.             End If
  181.         Next
  182.     End Sub
  183. End Class
  184.  
  185. ' A very simple serializable class
  186. <Serializable()> Class Point
  187.     Public X As Single
  188.     Public Y As Single
  189.  
  190.     Sub New(ByVal X As Single, ByVal Y As Single)
  191.         Me.X = X
  192.         Me.Y = Y
  193.     End Sub
  194.  
  195.     Overrides Function ToString() As String
  196.         Return "(" & X.ToString & "," & Y.ToString & ")"
  197.     End Function
  198. End Class
  199.  
  200. ' An array of Points that can serialize in a compact format
  201. ' provides an example of how to use IDeserializationCallback
  202.  
  203. <Serializable()> _
  204. Class CompactPointArray
  205.     Inherits ArrayList
  206.     Implements ISerializable, IDeserializationCallback
  207.  
  208.     ' This variable cashes the object passed to the constructor.    
  209.     Dim m_info As SerializationInfo
  210.  
  211.     ' We need this constructor.
  212.     Sub New()
  213.         MyBase.New()
  214.     End Sub
  215.  
  216.     ' The special constructor implied by ISerializable.
  217.     Private Sub New(ByVal info As SerializationInfo, _
  218.         ByVal context As StreamingContext)
  219.         ' Create an ArrayList object.
  220.         MyBase.New()
  221.         ' Cache the SerializationInfo object.
  222.         m_info = info
  223.     End Sub
  224.  
  225.     ' This method is called when the object graph has been
  226.     ' completely deserialized.
  227.     Sub OnDeserialization(ByVal sender As Object) _
  228.         Implements IDeserializationCallback.OnDeserialization
  229.         ' Retrieve number of elements .
  230.         Dim elCount As Integer = m_info.GetInt32("Count")
  231.  
  232.         Dim index As Integer, p As Point
  233.         For index = 0 To elCount - 1
  234.             Try
  235.                 ' Try to assign the value in the SerializationInfo.
  236.                 p = CType(m_info.GetValue(index.ToString, GetType(Point)), Point)
  237.             Catch
  238.                 ' if any error, use a default "null" Point object
  239.                 p = New Point(0, 0)
  240.             End Try
  241.             ' Add to the inner ArrayList.
  242.             MyBase.Add(p)
  243.         Next
  244.         ' We don't need this object any longer.
  245.         m_info = Nothing
  246.     End Sub
  247.  
  248.     ' Serialize only non-Nothing elements.
  249.     Sub GetObjectData(ByVal info As SerializationInfo, ByVal _
  250.         context As StreamingContext) Implements ISerializable.GetObjectData
  251.  
  252.         ' Remember the total number of elements.
  253.         info.AddValue("Count", MyBase.Count)
  254.  
  255.         ' Serialize only elements whose value is different from (0,0).
  256.         Dim index As Integer, p As Point
  257.         For index = 0 To MyBase.Count - 1
  258.             ' The AddValue method requires a specific type.
  259.             p = DirectCast(MyBase.Item(index), Point)
  260.             If p.X <> 0 Or p.Y <> 0 Then
  261.                 ' Add to SerializationInfo only if <> (0,0).
  262.                 info.AddValue(index.ToString, p)
  263.             End If
  264.         Next
  265.     End Sub
  266. End Class
  267.